#include "ets_sys.h"
#include "osapi.h"
#include "user_interface.h"
#include "espconn.h"
#include "user_config.h"

LOCAL struct espconn esp_conn;
LOCAL esp_tcp esptcp;

/******************************************************************************
 * FunctionName : tcp_server_sent_cb
 * Description  : data sent callback.
 * Parameters   : arg -- Additional argument to pass to the callback function
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
tcp_server_sent_cb(void *arg)
{
	//data sent successfully
	os_printf("tcp sent cb \r\n");
}
/******************************************************************************
 * FunctionName : tcp_server_recv_cb
 * Description  : receive callback.
 * Parameters   : arg -- Additional argument to pass to the callback function
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
tcp_server_recv_cb(void *arg, char *pusrdata, unsigned short length)
{
	//received some data from tcp connection
	//struct espconn *pespconn = arg;
	//os_printf("tcp recv : %s \r\n", pusrdata);
	//espconn_sent(pespconn, pusrdata, length);
	uart0_tx_buffer(pusrdata,length);
}
/******************************************************************************
 * FunctionName : tcp_server_discon_cb
 * Description  : disconnect callback.
 * Parameters   : arg -- Additional argument to pass to the callback function
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
tcp_server_discon_cb(void *arg)
{
	//tcp disconnect successfully
	os_printf("tcp disconnect succeed !!! \r\n");
}
/******************************************************************************
 * FunctionName : tcp_server_recon_cb
 * Description  : reconnect callback, error occured in TCP connection.
 * Parameters   : arg -- Additional argument to pass to the callback function
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
tcp_server_recon_cb(void *arg, sint8 err)
{
	//error occured , tcp connection broke.
	os_printf("reconnect callback, error code %d !!! \r\n",err);
}

void ICACHE_FLASH_ATTR tcp_server_multi_send(char *pbuf, uint16_t len)
{
	struct espconn *pesp_conn = &esp_conn;

	remot_info *premot = NULL;
	uint8 count = 0;
	sint8 value = ESPCONN_OK;
	if (espconn_get_connection_info(pesp_conn,&premot,0) == ESPCONN_OK){
		for (count = 0; count < pesp_conn->link_cnt; count ++){
				pesp_conn->proto.tcp->remote_port = premot[count].remote_port;
				pesp_conn->proto.tcp->remote_ip[0] = premot[count].remote_ip[0];
				pesp_conn->proto.tcp->remote_ip[1] = premot[count].remote_ip[1];
				pesp_conn->proto.tcp->remote_ip[2] = premot[count].remote_ip[2];
				pesp_conn->proto.tcp->remote_ip[3] = premot[count].remote_ip[3];
				espconn_sent(pesp_conn, pbuf, len);
	}
	}
}
/******************************************************************************
 * FunctionName : tcp_server_listen
 * Description  : TCP server listened a connection successfully
 * Parameters   : arg -- Additional argument to pass to the callback function
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
tcp_server_listen(void *arg)
{
	struct espconn *pesp_conn = arg;
	os_printf("tcp_server_listen !!! \r\n");
	espconn_regist_recvcb(pesp_conn, tcp_server_recv_cb);
	espconn_regist_reconcb(pesp_conn, tcp_server_recon_cb);
	espconn_regist_disconcb(pesp_conn, tcp_server_discon_cb);
	espconn_regist_sentcb(pesp_conn, tcp_server_sent_cb);

	int keep_alive = 10;   //keep alive checking per 30s
	espconn_set_opt(pesp_conn, ESPCONN_KEEPALIVE);
	espconn_set_keepalive(pesp_conn, ESPCONN_KEEPIDLE, &keep_alive);
	keep_alive = 2; //repeat interval = 5s
	espconn_set_keepalive(pesp_conn, ESPCONN_KEEPINTVL, &keep_alive);
	keep_alive = 5;//repeat 2times
	espconn_set_keepalive(pesp_conn, ESPCONN_KEEPCNT, &keep_alive);
}
/******************************************************************************
 * FunctionName : user_tcpserver_init
 * Description  : parameter initialize as a TCP server
 * Parameters   : port -- server port
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_tcpserver_init(uint32 port)
{
	esp_conn.type = ESPCONN_TCP;
	esp_conn.state = ESPCONN_NONE;
	esp_conn.proto.tcp = &esptcp;
	esp_conn.proto.tcp->local_port = port;
	espconn_regist_connectcb(&esp_conn, tcp_server_listen);
	sint8 ret = espconn_accept(&esp_conn);
	os_printf("espconn_accept [%d] !!! \r\n", ret);
}
